package com.maple.retry.retrytask.model;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.Map;

/**
 * @author: maple
 * @version: RetryTaskContext.java, v 0.1 2020年12月02日 10:23 maple Exp $
 */
public class RetryTaskContext implements Serializable {

    /**
     * serial version id
     */
    private static final long serialVersionUID = -982476406522279265L;

    private static final Logger logger = LoggerFactory.getLogger(RetryTaskContext.class);

    /**
     * 原业务数据实例的类型
     */
    private Class<?> clazz;

    /**
     * 原业务数据
     */
    private String bizContext;

    /**
     * 扩展数据
     */
    private String extInfo;

    /**
     * tracer 上下文
     */
    private String tracerContext;

    /**
     * 生成一个补偿任务上下文
     *
     * @param obj 根据一个业务数据生成一个补偿任务上下文
     * @return 补偿任务上下文
     */
    public static RetryTaskContext valueOf(Object obj) {

        return valueOf(obj, null);
    }

    /**
     * 生成一个补偿任务上下文
     *
     * @param obj 根据一个业务数据生成一个补偿任务上下文
     * @return 补偿任务上下文
     */
    public static RetryTaskContext valueOf(Object obj, Map<String, Object> ext) {

        try {
            RetryTaskContext compensateContext = new RetryTaskContext();
            compensateContext.setClazz(obj.getClass());
            compensateContext.setBizContext(JSON.toJSONString(obj));

            if (CollectionUtils.isNotEmpty(ext)) {
                compensateContext.setExtInfo(JSON.toJSONString(ext));
            }

            return compensateContext;
        } catch (Throwable t) {
            logger.error("construct CompensateContext failed", t);
            return null;
        }
    }

    /**
     * 获取反序列化以后的业务上下文
     *
     * @return 业务上下文 ;
     */
    public Object fetchDeserializedBizContext() {
        return JSON.parseObject(getBizContext(), getClazz());
    }

    /**
     * 获取反序列化以后的扩展信息
     *
     * @return extInfo
     */
    public Map fetchDeserializedExtInfo() {
        return JSON.parseObject(getExtInfo(), Map.class);
    }

    /**
     * Getter method for property clazz.
     *
     * @return property value of clazz
     */
    public Class<?> getClazz() {
        return clazz;
    }

    /**
     * Setter method for property clazz.
     *
     * @param clazz value to be assigned to property clazz
     */
    public void setClazz(Class<?> clazz) {
        this.clazz = clazz;
    }

    /**
     * Getter method for property tracerContext.
     *
     * @return property value of tracerContext
     */
    public String getTracerContext() {
        return tracerContext;
    }

    /**
     * Setter method for property tracerContext.
     *
     * @param tracerContext value to be assigned to property tracerContext
     */
    public void setTracerContext(String tracerContext) {
        this.tracerContext = tracerContext;
    }

    /**
     * Getter method for property <tt>extInfo</tt>.
     *
     * @return property value of extInfo
     */
    public String getExtInfo() {
        return extInfo;
    }

    /**
     * Getter method for property bizContext.
     *
     * @return property value of bizContext
     */
    public String getBizContext() {
        return bizContext;
    }

    /**
     * Setter method for property bizContext.
     *
     * @param bizContext value to be assigned to property bizContext
     */
    public void setBizContext(String bizContext) {
        this.bizContext = bizContext;
    }

    /**
     * Setter method for property <tt>extInfo</tt>.
     *
     * @param extInfo value to be assigned to property extInfo
     */
    public void setExtInfo(String extInfo) {
        this.extInfo = extInfo;
    }

    /**
     * @see Object#toString()
     */
    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}
